//
//  SQLiteManager.swift
//  SQLite使用(了解)
//
//  Created by iOS on 16/10/7.
//  Copyright © 2016年 iOS. All rights reserved.
//

/*
 代码使用数据库
    1.打开数据库
    2.创建表
    3.操作数据
 */

import UIKit

// 所有和数据库相关的操作都是sqlite3开头

class SQLiteManager: NSObject {

    static let shared: SQLiteManager = SQLiteManager()
    
    // ppDb: UnsafeMutablePointer<OpaquePointer?>!: 数据库对象
    var db: OpaquePointer? = nil
    
    // 作为移动端,数据库是保存在沙盒中的,只有我们的程序可以访问,其他程序访问不了.只需要打开一次就行.
    // 服务器的数据,一般会搞很多连接池.
    private override init() {
        super.init()
        let dbPath = NSSearchPathForDirectoriesInDomains(.documentDirectory, .userDomainMask, true).last! + "/sqlite.sqlite"
        print("dbPath: \(dbPath)")
        // filename: UnsafePointer<Int8>!: 数据库的路径
        // ppDb: UnsafeMutablePointer<OpaquePointer?>!: 数据库对象
        
        if sqlite3_open(dbPath, &db) != SQLITE_OK {
            print("打开数据库失败了")
            return
        }
        
        print("打开数据库成功了")
        
        createTable()
    }
    
    private func createTable() {
        // sql
        let sql = "CREATE TABLE IF NOT EXISTS T_Person (id INTEGER PRIMARY KEY AUTOINCREMENT, name TEXT, age INTEGER, height REAL);"
        
        // 执行sql
        if execSQL(sql: sql) {
            print("创建表成功")
        }
    }
    
    /// 执行sql语句
    ///
    /// - parameter sql: 要执行的sql语句
    ///
    /// - returns: 是否成功
    func execSQL(sql: String) -> Bool {
        // OpaquePointer!: 数据库对象
        // sql: UnsafePointer<Int8>!: 要执行的sql语句
        // callback: ((UnsafeMutableRawPointer?, Int32, UnsafeMutablePointer<UnsafeMutablePointer<Int8>?>?, UnsafeMutablePointer<UnsafeMutablePointer<Int8>?>?) -> Int32)!: 执行sql语句后的回调
        // UnsafeMutableRawPointer!:
        return sqlite3_exec(db, sql, nil, nil, nil) == SQLITE_OK
    }
    
    /// 查询数据
    func execQuery(sql: String) -> Void {
        // 1.准备sql
        // db: OpaquePointer!: 数据库对象
        // zSql: UnsafePointer<Int8>!: 要执行的sql语句
        // nByte: Int32: 要执行的sql语句的长度 -1 表示全部执行
        // ppStmt: UnsafeMutablePointer<OpaquePointer?>!: 查询的结果会保存在这个对象中
        // pzTail: UnsafeMutablePointer<UnsafePointer<Int8>?>!: 没有执行的sql语句
        var stmt: OpaquePointer? = nil
        if sqlite3_prepare_v2(db, sql, -1, &stmt, nil) != SQLITE_OK {
            print("准备sql失败了")
            return
        }
        
        print("准备sql成功了")
        // 所有的查询到的结果都依靠 stmt 来获取到, stmt并不是一次性将所有结果返回,一次返回一条
        // 单步执行,获取下一条数据
        while sqlite3_step(stmt) == SQLITE_ROW {
            // 获取到一条数据
            // 获取内容
            // OpaquePointer!: stmt
            // iCol: Int32: 第几列
            let id = sqlite3_column_int(stmt, 0)
            
            let cName = sqlite3_column_text(stmt, 1)!
            let name = String(cString: cName)
            
            let age = sqlite3_column_int(stmt, 2)
            
            let height = sqlite3_column_double(stmt, 3)
            print("id = \(id), name = \(name), age = \(age), height = \(height)")
        }
    }
}
